package org.jz.gae.redbook.spb.client.slate.species;

import java.util.ArrayList;
import java.util.List;

import org.jz.gae.redbook.spb.client.slate.location.LocationAppendPlate;
import org.jz.gae.redbook.spb.client.slate.location.LocationDetailPlate;
import org.jz.gae.redbook.spb.client.slate.location.LocationPropertiesPanel;
import org.jz.gae.redbook.spb.client.toolkit.EntityViewGrid;
import org.jz.gae.redbook.spb.client.toolkit.Slate;
import org.jz.gae.redbook.spb.client.toolkit.EntityViewGrid.ColumnValueDisplayer;
import org.jz.gae.redbook.spb.shared.LocationEntityView;
import org.jz.gae.redbook.spb.shared.MapHelper;
import org.jz.gae.redbook.spb.shared.SpeciesEntityView;

import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.maps.client.MapWidget;
import com.google.gwt.maps.client.control.LargeMapControl;
import com.google.gwt.maps.client.event.MarkerDragEndHandler;
import com.google.gwt.maps.client.event.MarkerDragEndHandler.MarkerDragEndEvent;
import com.google.gwt.maps.client.geom.LatLng;
import com.google.gwt.maps.client.overlay.Marker;
import com.google.gwt.maps.client.overlay.MarkerOptions;
import com.google.gwt.user.cellview.client.TextColumn;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.SimplePanel;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.VerticalPanel;

public class SpeciesDetailPlate extends Composite
{
      private VerticalPanel rootPanel = new VerticalPanel();
	  private final Button editButton = new Button("Изменить");
	  private final Button deleteButton = new Button("Удалить");;
	  private final Button closeButton = new Button("Закрыть");;
	  private SpeciesPropertiesPanel speciesPropertiesPanel = new SpeciesPropertiesPanel();
	  private Slate slate;
	  private SpeciesEntityView entityView;
      private ClickHandler changeEvent;
      
	  private final Button locationRefreshButton = new Button("Обновить");
	  private final Button locationAddButton = new Button("Добавить");
	  private final Button locationOpenButton = new Button("Открыть");
	  private final Button locationMapButton = new Button("Карта");
      
      private EntityViewGrid<LocationEntityView> locationListGrid = new EntityViewGrid<LocationEntityView>();


	public SpeciesDetailPlate() 
	{
		SimplePanel contentTableDecorator = new SimplePanel();
	  initWidget(contentTableDecorator);
	  contentTableDecorator.setWidth("100%");
	  initilizeInterface();
      contentTableDecorator.add(rootPanel);
      
      editButton.addClickHandler(new ClickHandler(){
    	  @Override
    	  public void onClick(ClickEvent event)
          {
              editSpecies();
    	  }
      });
      deleteButton.addClickHandler(new ClickHandler(){
    	  @Override
    	  public void onClick(ClickEvent event)
          {
              deleteSpecies();
    	  }
      });
      closeButton.addClickHandler(new ClickHandler(){
    	  @Override
    	  public void onClick(ClickEvent event)
          {
              closePlate();
    	  }
      });
	}

	private void initilizeInterface()
	{
		rootPanel.setWidth("100%");
		speciesPropertiesPanel.setWidth("100%");
		rootPanel.add(speciesPropertiesPanel);
	    HorizontalPanel menuPanel = new HorizontalPanel();
	    menuPanel.add(editButton);
	    menuPanel.add(deleteButton);
	    menuPanel.add(closeButton);
	    rootPanel.add(menuPanel);
	    speciesPropertiesPanel.lockInterface();
	    initializeLocationListGrid();
	    rootPanel.add(new Label("Местонахождения"));
	    rootPanel.add(locationListGrid);
	}
	
	private void initializeLocationListGrid()
	{
	    locationListGrid.setWidth("100%");
	    locationListGrid.addButton(locationRefreshButton);
	    locationListGrid.addButton(locationAddButton);
	    locationListGrid.addButton(locationOpenButton);
	    locationListGrid.addButton(locationMapButton);
	    locationListGrid.addGridColumn("Район", "180px", new ColumnValueDisplayer<LocationEntityView>(){
	    	@Override
	    	public String displayColumnValue(LocationEntityView _EntityView)
	    	{
	    		return _EntityView.getLocationDistrictPresentation();
	    	}
	    },
	    new TextColumn<LocationEntityView>(){
	    	@Override
	    	public String getValue(LocationEntityView _EntityView)
	    	{
	    		return _EntityView.getLocationDistrictPresentation();
	    	}
	    });

	    locationListGrid.addGridColumn("Рабочее наменование", null, new ColumnValueDisplayer<LocationEntityView>(){
	    	@Override
	    	public String displayColumnValue(LocationEntityView _EntityView)
	    	{
	    		return _EntityView.getLocationWorkName();
	    	}
	    },
	    new TextColumn<LocationEntityView>(){
	    	@Override
	    	public String getValue(LocationEntityView _EntityView)
	    	{
	    		return _EntityView.getLocationWorkName();
	    	}
	    });
	    locationRefreshButton.addClickHandler(new ClickHandler() {   
	        public void onClick(ClickEvent event) 
	        {
	        	fetchLocationDetails();
	        }
	      });
	    
	    locationAddButton.addClickHandler(new ClickHandler() {   
	        public void onClick(ClickEvent event) 
	        {
	        	appendNewLocation();
 	        }
	      });

	    locationOpenButton.addClickHandler(new ClickHandler() {   
	        public void onClick(ClickEvent event) 
	        {
	        	openSelectedLocation();
	        }
	      });
	    locationMapButton.addClickHandler(new ClickHandler() {   
	        public void onClick(ClickEvent event) 
	        {
	        	buildLocationMap();
	        }
	      });
	}

	public void openEntityView(
			Slate _Slate,
		    String _SpeciesId,	
			ClickHandler _ChangeEvent)
	{
		slate = _Slate;
		slate.getContainerAgent().getRpcService().getSpecies(_SpeciesId, new AsyncCallback<SpeciesEntityView>(){
			@Override
			public void onFailure(Throwable caught)
			{
				Window.alert("Ошибка загрузки семейства : " + caught.getMessage());
			}

			@Override
			public void onSuccess(SpeciesEntityView result)
			{
				entityView = result;
				speciesPropertiesPanel.displayInformation(entityView);
				fetchLocationDetails();
			}
		});
		changeEvent = _ChangeEvent;
		slate.exposePlate(this);
	}
	
	private void closePlate()
	{
		slate.closeTopPlate();
	}
	
	private void editSpecies()
	{
		try
		{
            String id = entityView.getSpeciesKey();
            /**/
            SpeciesEditPlate editPlate = new SpeciesEditPlate();
            editPlate.editEntityView(slate, id, new ClickHandler()
			{
				@Override
				public void onClick(ClickEvent event)
				{
					slate.closeTopPlate();
				}
			});
		}
		catch(Exception ex)
		{
            Window.alert("Invalid data : " + ex.getMessage());
		}
		
	}
	
	private void deleteSpecies()
	{
		Window.alert("Not yet implemented");
		slate.closeTopPlate();
	}
	
	  private void fetchLocationDetails() 
	  {
		    slate.getContainerAgent().getRpcService().getLocationsForSpecies(
		    		entityView.getSpeciesKey(),
		    		new AsyncCallback<ArrayList<LocationEntityView>>() {
				      public void onSuccess(ArrayList<LocationEntityView> result) 
				      {
				          locationListGrid.setData(result);
				      }
				      
				      public void onFailure(Throwable caught) {
				        Window.alert("Error fetching location details");
				      }
				    });
		  }

    private void appendNewLocation()
    {
        LocationAppendPlate appendPlate = new LocationAppendPlate()
        {
        	@Override
        	protected void initializeNewEntityView(
        			LocationEntityView _NewEntityView)
        	{
        		_NewEntityView.setLocationSpeciesKey(entityView.getSpeciesKey());
        		_NewEntityView.setLocationSpeciesPresentation(entityView.getSpeciesLatName());
        	}
        };
        appendPlate.appendEntityView(slate, new ClickHandler(){
           	  @Override
		        public void onClick(ClickEvent event)
		        {
		        	fetchLocationDetails();
		        }
        });
    }
	  
    private void openSelectedLocation()
    {
    	LocationEntityView location = locationListGrid.getSelectedEntityView();
    	if (location != null)
    	{
            String id = location.getLocationKey();
            /**/
            LocationDetailPlate detailsPlate = new LocationDetailPlate();
            detailsPlate.openEntityView(slate, id, null);
    	}
    	else
    	{
            System.err.println("event releasing : no location chosen");  
    	}
    }
    
    private void buildLocationMap()
    {
	    slate.getContainerAgent().getRpcService().getLocationsForSpecies(
	    		entityView.getSpeciesKey(),
	    		new AsyncCallback<ArrayList<LocationEntityView>>() {
			      public void onSuccess(ArrayList<LocationEntityView> result) 
			      {
    		      	locationMapButton.setEnabled(false);
			      	MapWidget mapWidget = new MapWidget();
			  	    LatLng mapCenter = LatLng.newInstance(MapHelper.MAP_CENTER_LAT, MapHelper.MAP_CENTER_LONG);
			  	    int mapZoomLevel = MapHelper.MAP_ZOOM_LEVEL;
			  	    mapWidget.setCenter(mapCenter, mapZoomLevel);
			  		mapWidget.setWidth("100%");
			  		mapWidget.setHeight("50em");
			  		mapWidget.addControl(new LargeMapControl());
			  		{
			  			for (LocationEntityView location : result)
			  			{
			  				LatLng locationPont = LatLng.newInstance(location.getLocationCoordLatitude(), location.getLocationCoordLongitude());
			  				MarkerOptions locationOptions =  MarkerOptions.newInstance();
			  				locationOptions.setClickable(false);
			  				locationOptions.setTitle(location.getLocationWorkName());
			  				final Marker locationMarker = new Marker(locationPont, locationOptions);
			  				mapWidget.addOverlay(locationMarker);
			  			}
			  		}
			  	    rootPanel.add(mapWidget);
			      }
			      
			      public void onFailure(Throwable caught) {
			        Window.alert("Error fetching location details");
			      }
			    });
    }
	
}